package com.xunqi.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
@MapperScan(basePackages = ClusterDruidConfig.PACKAGE, sqlSessionFactoryRef = "clusterSqlSessionFactory")
public class ClusterDruidConfig {

	private Logger logger = LoggerFactory.getLogger(this.getClass());
	/** cluster dao 所在的包 */
	public static final String PACKAGE = "com.xunqi.dao.cluster";
	// mapper所在目录
	private static final String MAPPER_LOCATION = "classpath:mapper/cluster/*.xml";
	@Value("${cluster.datasource.driverClassName}")
	private String driverClassName;
	@Value("${cluster.datasource.url}")
	private String url;
	@Value("${cluster.datasource.username}")
	private String username;
	@Value("${cluster.datasource.password}")
	private String password;
	@Value("${cluster.datasource.filters}")
	private String filters;
	@Value("${cluster.datasource.maxActive}")
	private int maxActive;
	@Value("${cluster.datasource.initialSize}")
	private int initialSize;
	@Value("${cluster.datasource.maxWait}")
	private int maxWait;
	@Value("${cluster.datasource.minIdle}")
	private int minIdle;
	@Value("${cluster.datasource.timeBetweenEvictionRunsMillis}")
	private int timeBetweenEvictionRunsMillis;
	@Value("${cluster.datasource.minEvictableIdleTimeMillis}")
	private int minEvictableIdleTimeMillis;
	@Value("${cluster.datasource.validationQuery}")
	private String validationQuery;
	@Value("${cluster.datasource.testWhileIdle}")
	private boolean testWhileIdle;
	@Value("${cluster.datasource.testOnBorrow}")
	private boolean testOnBorrow;
	@Value("${cluster.datasource.testOnReturn}")
	private boolean testOnReturn;
	@Value("${cluster.datasource.maxOpenPreparedStatements}")
	private int maxOpenPreparedStatements;

	// 初始化数据库连接
	@Bean(name = "clusterDataSource")
	public DataSource clusterDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setMaxActive(maxActive);
		dataSource.setInitialSize(initialSize);
		dataSource.setMaxWait(maxWait);
		dataSource.setMinIdle(minIdle);
		dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		dataSource.setValidationQuery(validationQuery);
		dataSource.setTestWhileIdle(testWhileIdle);
		dataSource.setTestOnBorrow(testOnBorrow);
		dataSource.setTestOnReturn(testOnReturn);
		dataSource.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
		try {
			dataSource.setFilters(filters);
		} catch (SQLException e) {
			logger.error("druid configuration initialization filter", e);
		}
		return dataSource;
	}

	// 数据源事务管理器
	@Bean(name = "clusterDataSourceTransactionManager")
	public DataSourceTransactionManager clusterDataSourceTransactionManager() {
		return new DataSourceTransactionManager(clusterDataSource());
	}

	// 创建Session
	@Bean(name = "clusterSqlSessionFactory")
	public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource clusterDataSource)
			throws Exception {
		final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(clusterDataSource);
		// MapperLocations(Resource[] mapperLocations)
		Resource[] mapperLocations = new PathMatchingResourcePatternResolver()
				.getResources(ClusterDruidConfig.MAPPER_LOCATION);
		sqlSessionFactoryBean.setMapperLocations(mapperLocations);
		return sqlSessionFactoryBean.getObject();
	}
}
